package com.budwk.app.sqfwV2.generator.dayingRoadExcel;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.bo.SqfwExcelJudgeRes;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseTemplateExcelGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.component.FireIssusComponent;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.centuryCity.SafeCheckTaskParamDataDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.AccommodatePeopleVo;
import com.budwk.app.sqfwV2.dto.image.FireSafetyOnDayingRoadExcelImageConfigBO;
import com.budwk.app.sqfwV2.enums.DayingRoadFileServiceEnum;
import com.budwk.app.sqfwV2.enums.RectificateTimeEnum;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * {unitName}“三合一”场所(含沿街门店)台账
 */

@Slf4j
public class ThreeAndOneSiteGenerator extends BaseTemplateExcelGenerator implements DayingRoadExcelGenerator {

    @Override
    protected String getTemplateName() {
        return DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_THREEONE.getFilePath();
    }

    /**
    * 可以参照 {@link com.budwk.app.sqfw.enums.DownLoadFileNameEnum}
    *
    * @return 文件名名称
    */
    @Override
    public String getDownloadFileName() {
        //TODO 在这里返回你生成的文件名名称，注意注意注意不用带上后缀
        return DayingRoadPdfComponent.getDictName(DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_THREEONE.getCode(), null);
    }

    /**
     * 用户自定义excel基础参数，比如表头这样的公用数据
     * @param excelParam 已经填充的基础数据据
     * @param excelCreateParam excel生成提供的原料
     */
    @Override
    protected void customerPopularSheetBaseParam(Map<String, Object> excelParam, SqfwExcelCreateCommonBO excelCreateParam) {
        log.info("ThreeAndOneSiteGenerator getBaseExcelParamDTO: {}", JSONObject.toJSONString(excelCreateParam.getBaseExcelParamDTO()));
        excelParam.put("unitName", StrUtil.formatStr(excelCreateParam.getBaseExcelParamDTO().getUnitName()));
    }

    @Override
    protected void customerPopularSheetDataParam(List<Map<String, Object>> listMap, SqfwExcelCreateCommonBO excelCreateParam) {
        List<Sqfw_formSummary_new> summaryList = DayingRoadPdfComponent.getSummaryList(listMap, excelCreateParam);
        SysDictService dictService = NutzIocUtils.getBean(SysDictService.class);
        log.info("ThreeAndOneSiteGenerator customerDataParam summaryList: {}", JSONObject.toJSONString(summaryList));
        int num = 1;
        for (Sqfw_formSummary_new summary : summaryList) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(summary.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            log.info("ThreeAndOneSiteGenerator customerDataParam roadPdfDTO: {}", JSONObject.toJSONString(roadPdfDTO));
            if (!isGenerateExcel(roadPdfDTO)) {
                continue;
            }
            // 构建数据
            Map<String, Object> map = buildExcelMap(roadPdfDTO, summary, dictService);
            map.put("num", num ++);
            listMap.add(map);
        }
        log.info("ThreeAndOneSiteGenerator customerDataParam end: {}", JSONObject.toJSONString(listMap));
    }

    private static Map<String, Object> buildBaseInfo(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, Sqfw_formSummary_new formSummary) {
        Map<String, Object> map = new HashMap<>();
        // 1 居委会名称
        String communityStr = "";
        String community = formSummary.getCommunity();
        if (StringUtils.isNotBlank(community)) communityStr = community.replace("社区", "居委会");
        map.put("communityStr", communityStr);
        // 2 单位场所名称
        map.put("placeName", StrUtil.replaceNullStr(roadPdfDTO.getPlaceName()));
        map.put("mainBusinessScopeName", DayingRoadPdfComponent.getDictName(roadPdfDTO.getMainBusinessScope(), null));
        map.put("address", StrUtil.replaceNullStr(roadPdfDTO.getAddress()));
        map.put("operator", StrUtil.replaceNullStr(roadPdfDTO.getOperator()));
        map.put("operatorTelephone", StrUtil.replaceNullStr(roadPdfDTO.getOperatorTelephone()));
        map.put("placeArea", StrUtil.replaceNullStr(roadPdfDTO.getPlaceArea()));
        map.put("staffNumber", DayingRoadPdfComponent.getDictName(roadPdfDTO.getStaffNumber(), null));
        return map;
    }

    private static void buildAccommodatePeople(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, Map<String, Object> map, SysDictService dictService, Sqfw_formSummary_new formSummary) {
        AccommodatePeopleVo a = roadPdfDTO.getAccommodatePeople();
        if (a == null) {
            map.put("residentialNum", 0);
            map.put("existProblem", CommonConstants.HORIAONTAL_LINE);
            map.put("rectificationSituation", CommonConstants.HORIAONTAL_LINE);
            map.put("rectificationDateStr", CommonConstants.HORIAONTAL_LINE);
            map.put("rectificationAfterPhoto", null);
            map.put("rectificationAfterPhotoStr", null);
            map.put("violationPhoto", null);
            map.put("violationPhotoStr", null);
            return;
        }
        // 住人方式
        getAccommodatePeopleVo(roadPdfDTO, map, dictService, formSummary);
        // 整改图片
        String rectificationAfterPhoto = StringUtils.isNotEmpty(a.getRectificationAfterPhoto()) ? a.getRectificationAfterPhoto() : roadPdfDTO.getVisitPictures();
        buildImage(map, "rectificationAfterPhoto", "rectificationAfterPhotoStr", rectificationAfterPhoto);
        // 违规住人照片
        buildImage(map, "violationPhoto", "violationPhotoStr", a.getViolationPhoto());
    }

    private static void getAccommodatePeopleVo(FireSafetyOnDayingRoadPdfDTO roadPdfDTO,  Map<String, Object> map, SysDictService dictService, Sqfw_formSummary_new formSummary) {
        map.put("existProblem", CommonConstants.HORIAONTAL_LINE); // 存在的问题
        map.put("rectificationSituation", CommonConstants.HORIAONTAL_LINE); // 整改情况
        map.put("rectificationDateStr", CommonConstants.HORIAONTAL_LINE); // 整改时间
        LocalDate rectificationDate = roadPdfDTO.getRectificationDate();
        if (rectificationDate != null) {
            map.put("rectificationDateStr", LocalDateTimeUtil.format(rectificationDate, DatePattern.NORM_DATE_PATTERN));
        }
        map.put("residentialNum", CommonConstants.HORIAONTAL_LINE); // 住人人数
        AccommodatePeopleVo a = roadPdfDTO.getAccommodatePeople();
        // 如果没有住人
        if (a == null) {
            return;
        }
        String residentialType = a.getResidentialType();
        // 2 没有住人
        if (residentialType.equals(DictConstants.RESIDENTS_FORM_STAY_NOPERSON)) {
            map.put("residentialNum", 0);
            return ;
        }
        // 3 住人情况 有住人
        map.put("residentialNum", StrUtil.formatStr(a.getResidentialNum()));
        if (FireIssusComponent.existAccommodatePeopleProblem(roadPdfDTO)) {
            Sys_dict sysDict = dictService.fetch(Cnd.where(Sys_dict::getCode, "=", residentialType));
            map.put("existProblem", sysDict.getName());
            if (RectificateTimeEnum.isNowRectification(a.getRectificateType())) {
                map.put("rectificationDateStr", DateUtil.format(formSummary.getCreateDate(), DatePattern.NORM_DATE_PATTERN));
                map.put("rectificationSituation", RectificateTimeEnum.IMMEDIATE_RECTIFICAIOTN.getName());
                return;
            }
            map.put("rectificationDateStr", LocalDateTimeUtil.format(roadPdfDTO.getRectificationDate(), DatePattern.NORM_DATE_PATTERN));
            map.put("rectificationSituation", RectificateTimeEnum.DEADLINE_RECTIFICATION.getName());
            return;
        }
        // 4 已整改
        if (residentialType.equals(DictConstants.RESIDENTS_FORM_RECTIFIED)) {
            map.put("existProblem", "住人已整改"); // 存在的问题
            map.put("rectificationSituation", "住人已整改"); // 整改情况
            map.put("rectificationDateStr", DateUtil.format(formSummary.getCreateDate(), DatePattern.NORM_DATE_PATTERN));
            return ;
        }
    }

    private Map<String, Object> buildExcelMap(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, Sqfw_formSummary_new formSummary, SysDictService dictService) {
        // 1 构建基本信息
        Map<String, Object> map = buildBaseInfo(roadPdfDTO, formSummary);
        // 2 住人人数
        buildAccommodatePeople(roadPdfDTO, map, dictService, formSummary);
        return map;
    }

    private static void buildImage(Map<String, Object> map, String imageKey, String imageKeyStr, String imageUrl) {
        List<byte[]> picture = null;
        if (StringUtils.isNotEmpty(imageUrl)) {
            picture = CommonFormOfficeUtils.addPictureToByteList(imageUrl, 1);
        }
        map.put(imageKey, Lists.newArrayList());
        map.put(imageKeyStr, "");
        if (picture != null && picture.size() > 0) {
            map.put(imageKey, picture);
        } else {
            map.put(imageKeyStr, "-");
        }
    }

    /**
     * ●生成表格注意事项：
     * ○【是否住人】状态为【否】时，不生成该表格。
     * ○【主要经营范围】状态为【旅馆】时，且【是否住人】状态不为【否】时，也不生成表格。
     *
     * 条件变为：生成【“三合一”场所】台账的条件，变更为，当【是否为三合一】状态为“是”，则生成。否则不生成
     * @param roadPdfDTO
     * @return
     */
    public boolean isGenerateExcel(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
        // 判断a5是否为重点场所 选择重点场所 不生成表格
        if (DayingRoadPdfComponent.isKeyLocations(roadPdfDTO)) {
            return false;
        }
        SafeCheckTaskParamDataDTO p = roadPdfDTO.getIsThreeOneSystem();
        if (p != null) {
            return "true".equals(p.getKey());
        }
        return false;
    }

    @Override
    protected void completeExcelFileCreateParam(ExcelFileCreateParamBO excelFileCreateParam) {

    }

    @Override
    protected void customerPopularRowDataMap(Map<String, Object> rowDataMap, SqfwExcelForSummaryBO forSummaryBO) {

    }

    /**
     * 如果在遍历之前就能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelCreateParam excel生成所需的最为全面的数据
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeErgodic(SqfwExcelCreateCommonBO excelCreateParam, Map<String, Object> excelParam) {
        return DayingRoadPdfComponent.getSqfwExcelJudgeRes(excelCreateParam, new ThreeAndOneSiteGenerator());
    }


    /**
     * 如果在遍历之后能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeCreate(Map<String, Object> excelParam) {
        return null;
    }

    @Override
    protected Class<?> getImageConfigBO() {
        return FireSafetyOnDayingRoadExcelImageConfigBO.class;
    }
}
